// src/utils/request.ts
import axios, {
    AxiosInstance,
    AxiosResponse,
    AxiosRequestConfig,
    AxiosError,
  } from 'axios';
  import { Alert } from 'react-native';
  import AsyncStorage from '@react-native-async-storage/async-storage';
  
  // 定义扩展的请求配置类型
  declare module 'axios' {
    interface AxiosRequestConfig {
      loading?: boolean;
      isToken?: boolean;
    }
  }
  
  // 定义响应数据结构
  interface ResponseData<T = any> {
    code: number;
    data: T;
    message: string;
    describe?: string;
  }
  
  class Request {
    private instance: AxiosInstance;
    private requestCount: number = 0;
    private requestMap: Map<string, AbortController> = new Map();
  
    constructor() {
      this.instance = axios.create({
        baseURL: process.env.API_BASE_URL, // 根据你的环境变量配置
        timeout: 10000,
        headers: {
          'Content-Type': 'application/json;charset=utf-8',
        },
      });
  
      this.setupInterceptors();
    }
  
    private showLoading() {
      this.requestCount++;
      // React Native 中可以使用自定义的加载指示器
      // 这里只是示例，实际项目中可以使用你喜欢的加载组件
      if (this.requestCount === 1) {
        // 显示加载指示器
        console.log('显示加载中...');
      }
    }
  
    private hideLoading() {
      this.requestCount--;
      if (this.requestCount === 0) {
        // 隐藏加载指示器
        console.log('隐藏加载中...');
      }
    }
  
    private setupInterceptors() {
      // 请求拦截器
      this.instance.interceptors.request.use(
        async (config: AxiosRequestConfig) => {
          const key = JSON.stringify(config.data) + config.url;
          const controller = new AbortController();
          config.signal = controller.signal;
  
          if (this.requestMap.has(key)) {
            this.requestMap.get(key)?.abort();
            this.requestMap.delete(key);
          } else {
            this.requestMap.set(key, controller);
          }
  
          const { loading = true, isToken = true } = config;
  
          if (loading) this.showLoading();
  
          if (isToken) {
            const token = await AsyncStorage.getItem('token');
            if (token) {
              config.headers = config.headers || {};
              config.headers.Authorization = `Bearer ${token}`;
            }
          }
  
          return config;
        },
        (error: AxiosError) => {
          return Promise.reject(error);
        }
      );
  
      // 响应拦截器
      this.instance.interceptors.response.use(
        (response: AxiosResponse<ResponseData>) => {
          const { data, config } = response;
          const { loading = true } = config;
  
          if (loading) this.hideLoading();
  
          if (data.code !== 200) {
            Alert.alert('错误', data.describe || data.message || '请求失败');
            
            if (data.code === 401) {
              // 处理登录过期，跳转到登录页
              console.log('登录状态已过期');
            }
            
            return Promise.reject(new Error(data.describe || data.message || '请求失败'));
          }
  
          return data;
        },
        (error: AxiosError) => {
          this.hideLoading();
          
          let errorMessage = '请求错误';
          if (error.message === 'Network Error') {
            errorMessage = '网络连接异常';
          } else if (error.message.includes('timeout')) {
            errorMessage = '请求超时';
          } else if (error.message.includes('Request failed with status code')) {
            errorMessage = `请求失败，状态码: ${error.message.substr(error.message.length - 3)}`;
          } else if (error.response?.data?.message) {
            errorMessage = error.response.data.message;
          }
  
          Alert.alert('错误', errorMessage);
          return Promise.reject(error);
        }
      );
    }
  
    public get<T = any>(url: string, params?: any, config?: AxiosRequestConfig): Promise<T> {
      return this.instance.get(url, { params, ...config });
    }
  
    public post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
      return this.instance.post(url, data, config);
    }
  
    public put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
      return this.instance.put(url, data, config);
    }
  
    public delete<T = any>(url: string, params?: any, config?: AxiosRequestConfig): Promise<T> {
      return this.instance.delete(url, { params, ...config });
    }
  }
  
  const request = new Request();
  export default request;